<script setup lang="ts">
import { ref, reactive, onMounted, computed, watch, nextTick } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';
import { useI18n } from 'vue-i18n';

const { t, locale } = useI18n();
const loginFormRef = ref();
const router = useRouter();
const route = useRoute();
const loginInfo = reactive({
  XCSRFToken: '',
  SessionID: '',
  IP: '',
  LoginTime: '',
  UserID: '',
  UserName: '',
  Role: ''
});
const isLoading = ref(false);
const typeOptions = computed(() => {
  locale.value;
  return [
    {
      value: 'Shared',
      label: t('LOGIN_TYPE_SHARED')
    },
    {
      value: 'Exclusive',
      label: t('LOGIN_TYPE_EXCLUSIVE')
    }
  ];
});
const loginForm = reactive({
  ip: (route.query.ip as string) || '',
  port: route.query.port ? parseInt(route.query.port as string) : 443,
  username: '',
  password: '',
  type: 'Shared'
});
const loginRules = computed(() => {
  return {
    ip: [
      { required: true, message: t('LOGIN_IP_REQUIRED'), trigger: 'blur' },
      {
        pattern: /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/,
        message: t('LOGIN_IP_INVALID'),
        trigger: 'blur'
      }
    ],
    port: [
      { required: true, message: t('LOGIN_PORT_REQUIRED'), trigger: 'blur' },
      {
        type: 'number',
        min: 1,
        max: 65535,
        message: t('LOGIN_PORT_RANGE'),
        trigger: 'blur'
      }
    ],
    username: [{ required: true, message: t('LOGIN_USERNAME_REQUIRED'), trigger: 'blur' }],
    password: [{ required: true, message: t('LOGIN_PASSWORD_REQUIRED'), trigger: 'blur' }],
    type: [{ required: true, message: t('LOGIN_TYPE_REQUIRED'), trigger: 'blur' }]
  };
});
interface CookieInfo {
  name: string;
  value: string;
  path?: string;
  domain?: string;
  expires?: string;
  httpOnly?: boolean;
  secure?: boolean;
}

function parseCookie(cookieStr: string): CookieInfo {
  const cookie: CookieInfo = {
    name: '',
    value: ''
  };
  const parts = cookieStr.split(';').map((part) => part.trim());
  const [name, value] = parts[0].split('=').map((p) => p.trim());
  cookie.name = name;
  cookie.value = value;
  for (let i = 1; i < parts.length; i++) {
    const [key, val] = parts[i].split('=').map((p) => p.trim());
    if (key === 'Path') cookie.path = val;
    if (key === 'Domain') cookie.domain = val;
    if (key === 'Expires') cookie.expires = val;
    if (key === 'HttpOnly') cookie.httpOnly = true;
    if (key === 'Secure') cookie.secure = true;
  }
  return cookie;
}

async function handleLogout(
  baseUrl: string,
  sessionId: string,
  csrfToken: string,
  cookie: CookieInfo
) {
  if (!sessionId || !csrfToken || !cookie || !cookie.name || !cookie.value) {
    return;
  }

  try {
    const logoutUrl = `${baseUrl}/UI/Rest/Sessions/${sessionId}`;
    await window.api.fetchData({
      method: 'delete',
      url: logoutUrl,
      headers: {
        From: 'WebUI',
        'X-CSRF-Token': csrfToken,
        cookie: `${cookie.name}=${cookie.value}`
      }
    });
  } catch (error) {
    console.error('登出失败:', error);
  }
}
const ensureConnectionUnique = async (): Promise<boolean> => {
  try {
    const result = await window.api?.tabView?.findExistingConnection?.(
      loginForm.ip,
      loginForm.port
    );
    if (result?.tabId) {
      window.electron?.ipcRenderer?.send('duplicate-connection-notify', {
        ip: loginForm.ip,
        port: loginForm.port,
        tabId: result.tabId
      });
      return false;
    }
  } catch (error) {
    console.error('Failed to check existing connection:', error);
  }
  return true;
};

const handleLogin = async () => {
  const valid = await loginFormRef.value.validate();
  if (!valid) return;

  // 先检查是否有重复的连接
  const unique = await ensureConnectionUnique();
  if (!unique) {
    return;
  }

  isLoading.value = true;
  const baseUrl = `https://${loginForm.ip}:${loginForm.port}`;
  const LoginUrl = baseUrl + '/UI/Rest/Login';
  const loginData = {
    UserName: loginForm.username,
    Password: loginForm.password,
    Domain: 'LocaliBMC',
    Type: 'Local'
  };

  try {
    // 检查IP是否已经在可信列表中
    const trustCheck = await window.api.dialog.isTrustedSite(loginForm.ip);
    const isTrusted = trustCheck?.isTrusted === true;

    // 如果不在可信列表中，先询问用户是否信任
    if (!isTrusted) {
      try {
        const trustResult = await window.api.dialog.askTrustSite({
          ip: loginForm.ip,
          texts: {
            title: t('TRUST_DIALOG_TITLE'),
            message: t('TRUST_DIALOG_MESSAGE', { ip: loginForm.ip }),
            detail: t('TRUST_DIALOG_DETAIL'),
            buttons: [t('TRUST_DIALOG_CONFIRM'), t('TRUST_DIALOG_CANCEL')]
          }
        });
        if (trustResult.response === 0) {
          // 用户选择信任并继续，保存到可信列表
          await window.api.dialog.addTrustedSite(loginForm.ip);
        } else {
          // 用户取消
          ElMessage.info(t('LOGIN_CANCELLED'));
          isLoading.value = false;
          return;
        }
      } catch (error) {
        // 用户关闭对话框
        ElMessage.info(t('LOGIN_CANCELLED'));
        isLoading.value = false;
        return;
      }
    }

    let res = await window.api.fetchData({
      method: 'post',
      url: LoginUrl,
      data: loginData,
      headers: {
        From: 'WebUI',
        'X-CSRF-Token': ''
      },
      rejectUnauthorized: false
    });

    if (!res.success) {
      const errorMessage = res.errorMessage
        ? t(res.errorMessage) || res.errorMessage
        : t('LOGIN_FAILED');
      ElMessage.error(errorMessage);
      isLoading.value = false;
      return;
    }

    if (res.data) {
      loginInfo.UserName = res.data.Session.UserName;
      loginInfo.XCSRFToken = res.data.XCSRFToken;
      loginInfo.UserID = res.data.Session.UserID;
      loginInfo.Role = res.data.Session.Role[0];
      loginInfo.IP = res.data.Session.IP;
      loginInfo.LoginTime = res.data.Session.LoginTime;
      loginInfo.SessionID = res.data.Session.SessionID || res.data.SessionID || '';
      const setCookies = res.headers['set-cookie'] || [];

      if (setCookies.length === 0) {
        ElMessage.error(t('LOGIN_FAILED_NO_COOKIE'));
        isLoading.value = false;
        return;
      }

      const cookie = parseCookie(setCookies[0]);
      const KVMLogin = baseUrl + '/UI/Rest/Services/KvmLogin';

      try {
        let kvmRes = await window.api.fetchData({
          method: 'post',
          url: KVMLogin,
          data: { Mode: loginForm.type },
          headers: {
            From: 'WebUI',
            'X-CSRF-Token': loginInfo.XCSRFToken,
            cookie: `${cookie.name}=${cookie.value}`
          },
          rejectUnauthorized: false
        });

        if (!kvmRes.success) {
          const errorMessage = kvmRes.errorMessage
            ? t(kvmRes.errorMessage) || kvmRes.errorMessage
            : t('LOGIN_KVM_FAILED');
          ElMessage.error(errorMessage);
          await handleLogout(baseUrl, loginInfo.SessionID, loginInfo.XCSRFToken, cookie);
          isLoading.value = false;
          return;
        }

        if (kvmRes.data) {
          const tabId =
            (route.query.tabId as string) ||
            (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'
              ? crypto.randomUUID()
              : `${Date.now()}`);
          const sessionPayload = {
            kvmIp: kvmRes.data.KvmIP,
            kvmPort: kvmRes.data.KvmPort,
            sessionId: kvmRes.data.SessionId,
            webSessionId: loginInfo.SessionID,
            title: kvmRes.data.Title,
            token: kvmRes.data.Token,
            privilege: kvmRes.data.Privilege,
            baseUrl: baseUrl,
            csrfToken: loginInfo.XCSRFToken,
            cookieName: cookie.name,
            cookieValue: cookie.value,
            loginIp: loginForm.ip,
            loginPort: loginForm.port.toString(),
            useCertificate: 'false'
          };

          try {
            const saveResult = await window.api?.session?.save?.(tabId, sessionPayload);
            if (!saveResult?.success) {
              throw new Error('会话缓存失败');
            }
          } catch (sessionError) {
            ElMessage.error(t('LOGIN_KVM_FAILED'));
            await handleLogout(baseUrl, loginInfo.SessionID, loginInfo.XCSRFToken, cookie);
            isLoading.value = false;
            return;
          }

          router.push({
            name: 'client',
            query: {
              tabId: tabId
            }
          });
        } else {
          ElMessage.error(t('LOGIN_KVM_FAILED_DATA'));
          await handleLogout(baseUrl, loginInfo.SessionID, loginInfo.XCSRFToken, cookie);
          isLoading.value = false;
        }
      } catch (kvmError: any) {
        const errorMessage = kvmError?.errorMessage
          ? t(kvmError.errorMessage) || kvmError.errorMessage
          : kvmError?.message || t('LOGIN_KVM_REQUEST_FAILED');
        ElMessage.error(errorMessage);
        await handleLogout(baseUrl, loginInfo.SessionID, loginInfo.XCSRFToken, cookie);
        isLoading.value = false;
      }
    } else {
      ElMessage.error(t('LOGIN_FAILED'));
      isLoading.value = false;
    }
  } catch (error: any) {
    const errorMessage = error?.errorMessage
      ? t(error.errorMessage) || error.errorMessage
      : error?.message || t('LOGIN_REQUEST_FAILED');
    ElMessage.error(errorMessage);
    isLoading.value = false;
  }
};
watch(
  () => locale.value,
  async () => {
    await nextTick();
    if (loginFormRef.value) {
      loginFormRef.value.clearValidate();
    }
  }
);

onMounted(() => {});
</script>
<template>
  <div class="login-page">
    <el-card class="login-card" :header="$t('HOME_CONNECT')">
      <el-form
        ref="loginFormRef"
        :model="loginForm"
        :rules="loginRules"
        :validate-on-rule-change="false"
        label-position="left"
        label-width="100px"
        class="login-form"
      >
        <el-form-item :label="$t('LOGIN_IP')" prop="ip">
          <el-input v-model="loginForm.ip" :placeholder="$t('LOGIN_IP_PLACEHOLDER')" clearable />
        </el-form-item>

        <el-form-item :label="$t('LOGIN_PORT')" prop="port">
          <el-input
            v-model.number="loginForm.port"
            :placeholder="$t('LOGIN_PORT_PLACEHOLDER')"
            clearable
          />
        </el-form-item>

        <el-form-item :label="$t('LOGIN_USERNAME')" prop="username">
          <el-input
            v-model="loginForm.username"
            :placeholder="$t('LOGIN_USERNAME_PLACEHOLDER')"
            clearable
          />
        </el-form-item>

        <el-form-item :label="$t('LOGIN_PASSWORD')" prop="password">
          <el-input
            v-model="loginForm.password"
            type="password"
            :placeholder="$t('LOGIN_PASSWORD_PLACEHOLDER')"
            clearable
          />
        </el-form-item>

        <el-form-item :label="$t('LOGIN_TYPE')" prop="type">
          <el-select v-model="loginForm.type" :placeholder="$t('LOGIN_TYPE_PLACEHOLDER')">
            <el-option
              v-for="item in typeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>

        <el-form-item>
          <el-button type="primary" class="login-btn" :loading="isLoading" @click="handleLogin">
            {{ $t('LOGIN_CONNECT') }}
          </el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<style scoped>
.login-page {
  height: 100vh;
  width: 100vw;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f5f7fa;
  padding: 20px;
}

.login-card {
  width: 40%;
  min-width: 400px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.login-card :deep(.el-card__header) {
  font-weight: 600;
  font-size: 16px;
}

.login-form {
  margin-top: 20px;
}

.login-form :deep(.el-select) {
  width: 100%;
}

.login-btn {
  width: 100%;
}
</style>
